package com.detection.yolo.task;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.dahuatech.hutool.core.thread.ThreadUtil;
import com.dahuatech.icc.exception.ClientException;
import com.dahuatech.icc.oauth.utils.HttpUtils;
import com.detection.common.config.DetectionConfig;
import com.detection.common.domain.hikvision.accessControlOnline.AccessControlView;
import com.detection.common.utils.CacheFileUtils;
import com.detection.dahua.config.OauthConfigUtil;
import com.detection.dahua.demo.oss.PicDownloadDemo;
import com.detection.dahua.model.accesscontrol.record.QueryRecordRequest;
import com.detection.dahua.model.accesscontrol.record.QueryRecordResponse;
import com.detection.dahua.model.brm.device.ChannelPageRequest;
import com.detection.dahua.model.brm.device.ChannelPageResponse;
import com.detection.dahua.model.brm.device.DevicePageResponse;
import com.detection.dahua.model.brm.device.DeviceTreeRequest;
import com.detection.dahua.model.datasync.DataSync;
import com.detection.dahua.service.IDahuaAccessService;
import com.detection.dahua.service.IDahuaDeviceService;
import com.detection.hikvision.service.ArtemisCamerasService;
import com.detection.tcp.client.NettyTcpClient;
import com.detection.tcp.domain.TCPMessage;
import com.detection.tcp.filetransfer.client.FileUploadClient;
import com.detection.tcp.utils.DockingUtils;
import com.detection.tcp.utils.ParseUtils;
import com.detection.yolo.constant.Constants;
import com.example.network.demos.tcp.domain.FileUploadFile;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

import static com.detection.tcp.utils.DockingUtils.postForTCP;

@Component
@Slf4j
public class DahuaDeviceTask {

    @Autowired
    IDahuaDeviceService dahuaDeviceService;
    @Autowired
    private NettyTcpClient nettyTcpClient;
    @Autowired
    private IDahuaAccessService dahuaAccessService;
    @Autowired
    private PicDownloadDemo picDownloadDemo;

    @Autowired
    private FileUploadClient fileUploadClient;

    @Scheduled(cron = "0 0/5 * * * ?")
    public void updateVariable() throws InterruptedException {
        if (!"dahua".equals(DetectionConfig.getIOTplatform())){
            return;
        }
        ThreadUtil.execAsync(new Runnable() {
            @Override
            public void run() {
                List<DataSync> dataSyncList = null;

                DeviceTreeRequest deviceTreeRequest = new DeviceTreeRequest();
                deviceTreeRequest.setType("001;;1");
                deviceTreeRequest.setCheckStat(1);
                dataSyncList = dahuaDeviceService.getDeviceTreeSync(deviceTreeRequest);
                List<String> deviceCodeList = dataSyncList.stream().filter(fs -> "1".equals(fs.getTreeCode())).map(DataSync::getDeviceCode).collect(Collectors.toList());
                Map<String, Integer> deviceMap = new HashMap<>(16);
                deviceMap = getDeviceListByDeviceCode(deviceCodeList, deviceMap);
                for (DataSync oneDataSync : dataSyncList) {
                    if ("1".equals(oneDataSync.getTreeCode())) {
                        oneDataSync.setIsOnline(deviceMap.get(oneDataSync.getDeviceCode()));
                    }
                }
                int batchSize = 30;
                for (int i = 0; i < dataSyncList.size(); i += batchSize){
                    List<DataSync> subList = dataSyncList.subList(i, Math.min(i + batchSize, dataSyncList.size()));
                    TCPMessage message = new TCPMessage();
                    message.setId("11");
                    message.setFlag("SynchronizeVideoList");
                    message.setData(subList);
                    message.setCampCode(DetectionConfig.getCampCode());
                    nettyTcpClient.sendMessage(message);
                    postForTCP(message);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });

    }

    @Scheduled(cron = "0 0/5 * * * ?")
    public void updateAccessDevice() throws InterruptedException {
        if (!"dahua".equals(DetectionConfig.getIOTplatform())){
            return;
        }
        ThreadUtil.execAsync(new Runnable() {
            @Override
            public void run() {
                List<AccessControlView> accessControlViewList = new ArrayList<>();
                List<DevicePageResponse> accessDeviceList = dahuaDeviceService.getAccessDeviceList();

                for (DevicePageResponse devicePage : accessDeviceList) {
                    List<DevicePageResponse.PageVO.DeviceInfoVO> pageData = devicePage.getData().getPageData();
                    for (DevicePageResponse.PageVO.DeviceInfoVO deviceInfoVO : pageData) {
                        List<DevicePageResponse.PageVO.DeviceInfoVO.UnitVO> units = deviceInfoVO.getUnits();
                        String channelCode = "";
                        for (DevicePageResponse.PageVO.DeviceInfoVO.UnitVO unitVO : units) {
                            if (!"001111".equals(unitVO.getCapability())) {
                                continue;
                            }
                            List<DevicePageResponse.PageVO.DeviceInfoVO.UnitVO.ChannelVO> channels = unitVO.getChannels();
                            for (DevicePageResponse.PageVO.DeviceInfoVO.UnitVO.ChannelVO channelVO : channels) {
                                channelCode = channelVO.getChannelCode();
                            }
                        }
                        AccessControlView accessControlView = new AccessControlView();
                        accessControlView.setDoorIndexCode(channelCode);
                        accessControlView.setIndexCode(channelCode);
                        accessControlView.setOnline(String.valueOf(deviceInfoVO.getIsOnline()));
                        accessControlView.setDeviceType(deviceInfoVO.getDeviceCode());
                        accessControlView.setCn(deviceInfoVO.getDeviceName());
                        accessControlView.setCollectTime(DateUtil.now());
                        accessControlView.setRegionName(DetectionConfig.getCampName());
                        accessControlView.setCampCode(DetectionConfig.getCampCode());
                        accessControlView.setCampName(DetectionConfig.getCampName());
                        accessControlViewList.add(accessControlView);
                    }
                }

                int batchSize = 30;

                for (int i = 0; i < accessControlViewList.size(); i += batchSize) {
                    List<AccessControlView> subList = accessControlViewList.subList(i, Math.min(i + batchSize, accessControlViewList.size()));
                    TCPMessage message = new TCPMessage();
                    message.setFlag("SynchronizeAccseeList");
                    message.setData(JSON.toJSONString(subList));
                    message.setCampCode(DetectionConfig.getCampCode());
                    message = ParseUtils.parse(message);
                    nettyTcpClient.sendMessage(message);
                    DockingUtils.postForTCP(message);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });

    }


    @Scheduled(cron = "0 0/5 * * * ?")
    public void updateAccessControlVariable() throws ClientException, InterruptedException {
        if (!"dahua".equals(DetectionConfig.getIOTplatform())){
            return;
        }
        ThreadUtil.execAsync(new Runnable() {
            @Override
            public void run() {
                Object startDateObj = CacheFileUtils.getCache("accessControl_startDate");
                Date endDate = new Date();

                String endDateStr = DateUtil.format(endDate,"yyyy-MM-dd HH:mm:ss");
                // 五分钟前的数据
                String startDate = DateUtil.format(new Date(endDate.getTime()-300000),"yyyy-MM-dd HH:mm:ss");
                if(Objects.nonNull(startDateObj)){
                    startDate = startDateObj.toString();
                }
                QueryRecordRequest queryRecordRequest = new QueryRecordRequest();

                queryRecordRequest.setStartSwingTime(startDate);
                queryRecordRequest.setEndSwingTime(endDateStr);
                queryRecordRequest.setPageNum(1);
                queryRecordRequest.setPageSize(20000);
                QueryRecordResponse recordPage = dahuaAccessService.getRecordPage(queryRecordRequest);
                List<QueryRecordResponse.Data.PageData> pageDataList = recordPage.getData().getPageData();
                List<QueryRecordResponse.Data.PageData> pageDataListLocal = recordPage.getData().getPageData();
                for(QueryRecordResponse.Data.PageData pageData: pageDataList){
                    String recordImageUrl = pageData.getRecordImageUrl();
                    QueryRecordResponse.Data.PageData pageData1 = pageData;
                    try {
                        recordImageUrl = getImageBase64(recordImageUrl);

                    } catch (Exception e) {

                        throw new RuntimeException(e);
                    }
                    pageData.setRecordImageUrl(DetectionConfig.getSendAddress()+recordImageUrl);
                    pageData1.setRecordImageUrl("http://"+DetectionConfig.getSendTCPIP()+recordImageUrl);
                    pageDataListLocal.add(pageData1);
                }
                int batchSize = 20;
                for (int i = 0; i < pageDataList.size(); i += batchSize){
                    List<QueryRecordResponse.Data.PageData> subList = pageDataList.subList(i, Math.min(i + batchSize, pageDataList.size()));
                    List<QueryRecordResponse.Data.PageData> subList1 = pageDataListLocal.subList(i, Math.min(i + batchSize, pageDataListLocal.size()));

                    TCPMessage message = new TCPMessage();
                    message.setId("12");
                    message.setFlag("updateAccessControl");
                    message.setData(subList);
                    message.setCampCode(DetectionConfig.getCampCode());
                    nettyTcpClient.sendMessage(message);
                    message.setData(subList1);
                    DockingUtils.postForTCP(message);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                CacheFileUtils.setCache("accessControl_startDate",endDateStr);

            }
        });

    }

    public String getImageBase64(String recordImageUrl) throws Exception {
        String token = HttpUtils.getToken(OauthConfigUtil.getOauthConfig()).getAccess_token();
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("https://"+OauthConfigUtil.getOauthConfig().getHttpConfigInfo().getHost()+":443/evo-apigw/evo-oss/");
        stringBuffer.append(recordImageUrl);
        stringBuffer.append("?token=" + token);
        String destPath =  "/dahuaaccess/"+DateUtil.format(new Date(),"yyyy-MM-dd");
        File destPathFile = new File(DetectionConfig.getProfile()+destPath);
        if(!destPathFile.exists()){
            destPathFile.mkdirs();
        }
        picDownloadDemo.download(stringBuffer.toString(),DetectionConfig.getProfile()+destPath);
        String url1 = stringBuffer.toString().substring(stringBuffer.toString().lastIndexOf("/"));
        String url2 = url1.substring(1, url1.lastIndexOf("?"));
        sendTcpFile(DetectionConfig.getProfile()+destPath + "/" + url2);
        return  Constants.RESOURCE_PREFIX+destPath + "/" + url2;
    }


    private Map<String, Integer> getDeviceListByDeviceCode(List<String> deviceCodeList, Map<String, Integer> deviceMap) {
        Integer size = deviceCodeList.size();
        if (size <= 500) {
            return getDeviceMap(size, deviceCodeList, deviceMap);
        } else {
            List<String> current = deviceCodeList.subList(0, 499);
            size = current.size();
            deviceMap = getDeviceMap(size, current, deviceMap);
            List<String> other = deviceCodeList.subList(500, deviceCodeList.size());
            return getDeviceListByDeviceCode(other, deviceMap);
        }
    }

    public Map<String, Integer> getDeviceMap(Integer size, List<String> deviceCodeList, Map<String, Integer> deviceMap) {
        ChannelPageRequest channelPageRequest = new ChannelPageRequest();
        channelPageRequest.setPageNum(1);
        channelPageRequest.setPageSize(size);
        channelPageRequest.setDeviceCodeList(deviceCodeList);
        //查询视频通道
        channelPageRequest.setUnitTypeList(Arrays.asList(1));
        ChannelPageResponse channelPageResponse = dahuaDeviceService.getChannelPage(channelPageRequest);
        List<ChannelPageResponse.PageVO.ChannelInfoVO> channelInfoVOS = channelPageResponse.getData().getPageData();
        channelInfoVOS.stream().forEach(channel -> deviceMap.put(channel.getDeviceCode(), channel.getIsOnline()));
        return deviceMap;
    }

    private void sendTcpFile(String fileFullPath) throws Exception {
        FileUploadFile uploadFile = new FileUploadFile();
        File file = new File(fileFullPath);
        String fileMd5 = file.getName();// 文件名
        uploadFile.setFile(file);
        uploadFile.setFile_md5(fileMd5);
        uploadFile.setStarPos(0);// 文件开始位置
        uploadFile.setFilePath(fileFullPath.replace(DetectionConfig.getProfile(),""));
        fileUploadClient.connect(uploadFile);
        log.info("发送文件成功: {}", fileFullPath);
    }
}
